/**
 * 加载控件
 *
 * Created by GUY on 2015/8/31.
 * @class BI.Loader
 * @extends BI.Widget
 */
BI.MultiSelectInnerLoader = BI.inherit(BI.Widget, {
    _defaultConfig: function () {
        return BI.extend(BI.MultiSelectInnerLoader.superclass._defaultConfig.apply(this, arguments), {
            baseCls: "bi-multi-select-inner-loader",

            direction: "top",
            isDefaultInit: true, // 是否默认初始化数据
            logic: {
                dynamic: true,
                scrolly: true
            },

            // 下面是button_group的属性
            el: {
                type: "bi.button_group",
                chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI,
                behaviors: {
                    redmark: function () {
                        return true;
                    }
                },
                layouts: [{
                    type: "bi.vertical"
                }]
            },

            items: [],
            itemsCreator: BI.emptyFn,
            onLoaded: BI.emptyFn,

            // 下面是分页信息
            count: false,
            prev: false,
            next: {},
            hasPrev: BI.emptyFn,
            hasNext: BI.emptyFn
        });
    },

    _nextLoad: function () {
        var self = this, o = this.options;
        this.next.setLoading();
        if (this.cachItems && this.cachItems.length > 0) {
            this.next.setLoaded();
            this.addItems(this.cachItems.slice(0, 100));
            this.cachItems = this.cachItems.slice(100);
            return;
        }
        o.itemsCreator.apply(this, [{times: ++this.times}, function () {
            self.next.setLoaded();
            self.addItems.apply(self, arguments);
        }]);
    },

    render: function () {
        var self = this, o = this.options;
        if (o.itemsCreator === false) {
            o.next = false;
        }
        this.button_group = BI.createWidget(o.el, {
            type: "bi.button_group",
            chooseType: 0,
            items: o.items,
            behaviors: {},
            layouts: [{
                type: "bi.vertical"
            }],
            value: o.value
        });
        this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) {
            if (type === BI.Events.CLICK) {
                var node = self.cachGroup.getNodeByValue(value);
                if (node) {
                    node.setSelected(obj.isSelected());
                }
            }
            self.fireEvent(BI.Controller.EVENT_CHANGE, arguments);
            if (type === BI.Events.CLICK) {
                self.fireEvent(BI.Loader.EVENT_CHANGE, obj);
            }
        });

        var renderEngine = BI.Widget._renderEngine;
        BI.Widget.registerRenderEngine(BI.Element.renderEngine);
        this.cachGroup = BI.createWidget(o.el, {
            type: "bi.button_group",
            root: true,
            chooseType: 0,
            items: o.items,
            behaviors: {},
            layouts: [{
                type: "bi.vertical"
            }],
            value: o.value
        });
        BI.Widget.registerRenderEngine(renderEngine);

        if (o.next !== false) {
            this.next = BI.createWidget(BI.extend({
                type: "bi.loading_bar"
            }, o.next));
            this.next.on(BI.Controller.EVENT_CHANGE, function (type) {
                if (type === BI.Events.CLICK) {
                    self._nextLoad();
                }
            });
        }

        BI.createWidget({
            type: "bi.vertical",
            element: this,
            items: [this.button_group, this.next]
        });

        o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () {
            o.isDefaultInit && BI.isEmpty(o.items) && this._populate();
        }, this));
    },

    hasNext: function () {
        var o = this.options;
        if (BI.isNumber(o.count)) {
            return this.count < o.count;
        }
        if (this.cachItems && this.cachItems.length > 0) {
            return true;
        }
        return !!o.hasNext.apply(this, [{
            times: this.times,
            count: this.count
        }]);
    },

    addItems: function (items) {
        this.count += items.length;
        if (BI.isObject(this.next)) {
            if (this.hasNext()) {
                this.options.items = this.options.items.concat(items);
                this.next.setLoaded();
            } else {
                this.next.setEnd();
            }
        }
        var renderEngine = BI.Widget._renderEngine;
        BI.Widget.registerRenderEngine(BI.Element.renderEngine);
        this.cachGroup.addItems.apply(this.cachGroup, arguments);
        BI.Widget.registerRenderEngine(renderEngine);
        this.button_group.addItems.apply(this.button_group, arguments);
    },

    _populate: function (items) {
        var self = this, o = this.options;
        if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) {
            o.itemsCreator.apply(this, [{times: 1}, function (items, keyword) {
                if (arguments.length === 0) {
                    throw new Error("参数不能为空");
                }
                self.populate.apply(self, arguments);
                o.onLoaded();
            }]);
            return false;
        }
        this.options.items = (items || []).slice(0, 100 + (items || []).length % 100);
        this.times = 1;
        this.count = 0;
        this.count += items.length;
        if (BI.isObject(this.next)) {
            if (this.hasNext()) {
                this.next.setLoaded();
            } else {
                this.next.invisible();
            }
        }
        return true;
    },

    populate: function (items, keyword) {
        if (this._populate.apply(this, arguments)) {
            this.cachItems = [];
            var firstItemsCount = 100 + items.length % 100;
            if (items.length > firstItemsCount) {
                this.cachItems = items.slice(firstItemsCount);
            }
            var renderEngine = BI.Widget._renderEngine;
            BI.Widget.registerRenderEngine(BI.Element.renderEngine);
            this.cachGroup.populate.call(this.cachGroup, items, keyword);
            BI.Widget.registerRenderEngine(renderEngine);
            this.button_group.populate.call(this.button_group, items.slice(0, firstItemsCount), keyword);
        }
    },

    setNotSelectedValue: function () {
        this.button_group.setNotSelectedValue.apply(this.button_group, arguments);
        this.cachGroup.setNotSelectedValue.apply(this.cachGroup, arguments);
    },

    getNotSelectedValue: function () {
        return this.cachGroup.getNotSelectedValue();
    },

    setAllSelected: function (v) {
        this.button_group.setAllSelected(v);
        this.cachGroup.setAllSelected(v);
    },

    setValue: function (value) {
        var map = BI.makeObject(BI.isArray(value) ? value : [value]);
        this.cachGroup.setValueMap.call(this.cachGroup, map);
        this.button_group.setValueMap.call(this.button_group, map);
    },

    getValue: function () {
        return this.cachGroup.getValue.apply(this.cachGroup, arguments);
    },

    getAllButtons: function () {
        return this.button_group.getAllButtons();
    },

    getAllLeaves: function () {
        return this.button_group.getAllLeaves();
    },

    getSelectedButtons: function () {
        return this.button_group.getSelectedButtons();
    },

    getNotSelectedButtons: function () {
        return this.button_group.getNotSelectedButtons();
    },

    getIndexByValue: function (value) {
        return this.button_group.getIndexByValue(value);
    },

    getNodeById: function (id) {
        return this.button_group.getNodeById(id);
    },

    getNodeByValue: function (value) {
        return this.button_group.getNodeByValue(value);
    },

    empty: function () {
        this.button_group.empty();
        this.cachGroup.empty();
        BI.each([this.prev, this.next], function (i, ob) {
            ob && ob.setVisible(false);
        });
    }
});
BI.MultiSelectInnerLoader.EVENT_CHANGE = "EVENT_CHANGE";
BI.shortcut("bi.multi_select_inner_loader", BI.MultiSelectInnerLoader);
